import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import {
  computed,
  defineComponent,
  h,
  PropType,
  resolveComponent,
  VNode,
  VNodeArrayChildren,
  watch,
} from 'vue';
import { TableColumnCtx } from 'element-plus';
import { IDEGrid, IDEGridColumn, IDEGridGroupColumn } from '@ibiz/model-core';
import { ControlVO } from '@ibiz-template/runtime';
import { useAppGridPagination, useITableEvent } from './grid-control.util';
import './grid.scss';
import { GridController } from './grid.controller';
import { GridRowState } from './grid-row.state';

export const GridControl = defineComponent({
  name: 'IBizGridControl',
  props: {
    modelData: { type: Object as PropType<IDEGrid>, required: true },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    /**
     * 部件行数据默认激活模式
     * - 0 不激活
     * - 1 单击激活
     * - 2 双击激活(默认值)
     *
     * @type {(number | 0 | 1 | 2)}
     */
    mdctrlActiveMode: { type: Number, default: undefined },
    singleSelect: { type: Boolean, default: undefined },
    isSimple: { type: Boolean, required: false },
    data: { type: Array<IData>, required: false },
  },
  setup(props) {
    const c = useControlController((...args) => new GridController(...args));
    const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);

    const {
      tableRef,
      onRowClick,
      onDbRowClick,
      onSelectionChange,
      onSortChange,
      handleRowClassName,
    } = useITableEvent(c);
    const { onPageChange, onPageRefresh, onPageSizeChange } =
      useAppGridPagination(c);

    const initSimpleData = (): void => {
      if (!props.data) {
        return;
      }
      c.state.items = props.data;
      c.state.rows = props.data.map(item => {
        const row = new GridRowState(new ControlVO(item), c);
        return row;
      });
    };

    // 选中数据回显
    c.evt.on('onCreated', async () => {
      if (props.isSimple) {
        initSimpleData();
        c.state.isLoaded = true;
      }
    });

    watch(
      () => props.data,
      () => {
        if (props.isSimple) {
          initSimpleData();
        }
      },
      {
        deep: true,
      },
    );

    // 表格数据，items和rows更新有时间差，用rows来获取items
    const tableData = computed(() => {
      const state = c.state;
      if (c.model.enableGroup) {
        const result: IData[] = [];
        state.groups.forEach(item => {
          if (!item.children.length) {
            return;
          }
          const children = [...item.children];
          const first = children.shift();
          result.push({
            srfkey: first?.srfkey || item.caption,
            isGroupData: true,
            caption: item.caption,
            first,
            children,
          });
        });
        return result;
      }
      return state.rows.map(row => row.data);
    });

    // 实际绘制的表格列
    const renderColumns = computed(() => {
      if (c.isMultistageHeader) {
        return c.model.degridColumns || [];
      }
      const columns: IDEGridColumn[] = [];
      c.state.columnStates.forEach(item => {
        if (item.hidden) {
          return;
        }
        const columnModel = c.fieldColumns[item.key].model;
        if (columnModel) {
          columns.push(columnModel);
        }
      });
      return columns;
    });

    const renderNoData = (): VNode | false => {
      // 未加载不显示无数据
      const { isLoaded } = c.state;
      return isLoaded && <iBizNoData></iBizNoData>;
    };

    /**
     * 求和计算回调
     * @author lxm
     * @date 2023-08-07 05:21:31
     * @return {*}  {string[]}
     */
    const summaryMethod = ({
      columns,
      data,
    }: {
      columns: TableColumnCtx<IData>[];
      data: IData[];
    }): string[] => {
      console.log(columns, data);

      return columns.map((item, index) => {
        if (index === 0) {
          return c.aggTitle;
        }
        return c.state.aggResult[item.property];
      });
    };

    return {
      c,
      ns,
      tableRef,
      tableData,
      renderColumns,
      onDbRowClick,
      onRowClick,
      onSelectionChange,
      onSortChange,
      onPageChange,
      onPageSizeChange,
      onPageRefresh,
      handleRowClassName,
      renderNoData,
      summaryMethod,
    };
  },
  render() {
    const state = this.c.state;
    const { hideHeader, enablePagingBar, minorSortAppDEFieldId, minorSortDir } =
      this.c.model;

    // 绘制除分组列之外的表格列
    const renderColumn = (
      model: IDEGridColumn,
      index: number,
    ): VNode | null => {
      if (model.hideDefault) {
        return null;
      }
      const { codeName: columnName, width } = model;
      const columnC = this.c.columns[columnName!];

      // 如果没有配置自适应列，则最后一列变为自适应列
      const widthFlexGrow =
        columnC.isAdaptiveColumn ||
        (!this.c.hasAdaptiveColumn && index === this.renderColumns.length - 1);

      const widthName = widthFlexGrow ? 'min-width' : 'width';
      // 表格列自定义
      return (
        <el-table-column
          label={model.caption}
          prop={columnName}
          {...{ [widthName]: width }}
          show-overflow-tooltip={model.columnType === 'DEFGRIDCOLUMN'}
          sortable={model.enableSort ? 'custom' : false}
          align={model.align?.toLowerCase() || 'center'}
        >
          {{
            default: ({ row }: IData): VNode | null => {
              let elRow = row; // element表格数据
              if (row.isGroupData) {
                // 有第一条数据时，分组那一行绘制第一条数据
                elRow = row.first;
              }

              const rowState = state.rows.find(
                item => item.data.srfkey === elRow.srfkey,
              );
              if (rowState) {
                const comp = resolveComponent(
                  this.c.providers[columnName!].component,
                );
                return h(comp, {
                  controller: columnC,
                  row: rowState,
                  key: elRow.srfkey + columnName,
                });
              }
              return null;
            },
          }}
        </el-table-column>
      );
    };

    // 绘制表格列
    const renderChildColumn = (
      model: IDEGridColumn,
      index: number,
    ): VNode | null => {
      if (model.columnType === 'GROUPGRIDCOLUMN') {
        const childColumns =
          (model as IDEGridGroupColumn).degridColumns?.filter(
            item => !item.hideDefault,
          ) || [];
        const { width } = model;
        const align = model.align?.toLowerCase() || 'center';
        return (
          <el-table-column
            label={model.caption}
            min-width={width}
            align={align}
          >
            {{
              default: (): VNodeArrayChildren => {
                return childColumns.map((column, index2) => {
                  return renderChildColumn(column, index2);
                });
              },
            }}
          </el-table-column>
        );
      }
      return renderColumn(model, index);
    };

    return (
      <iBizControlBase
        class={[
          this.ns.is('show-header', !hideHeader),
          this.ns.is('enable-page', enablePagingBar),
          this.ns.is('enable-group', this.c.model.enableGroup),
        ]}
        controller={this.c}
      >
        <el-table
          ref={'tableRef'}
          class={this.ns.e('table')}
          default-sort={{
            prop: minorSortAppDEFieldId,
            order: minorSortDir === 'desc' ? 'descending' : 'ascending',
          }}
          border
          show-header={!hideHeader}
          show-summary={this.c.enableAgg}
          summary-method={this.summaryMethod}
          highlight-current-row={state.singleSelect}
          row-class-name={this.handleRowClassName}
          row-key={'srfkey'}
          data={this.tableData}
          onRowClick={this.onRowClick}
          onRowDblclick={this.onDbRowClick}
          onSelectionChange={this.onSelectionChange}
          onSortChange={this.onSortChange}
        >
          {{
            empty: this.renderNoData,
            default: (): VNodeArrayChildren => {
              return [
                !state.singleSelect && (
                  <el-table-column
                    class-name={this.ns.e('selection')}
                    type='selection'
                    width='55'
                  ></el-table-column>
                ),
                state.isCreated &&
                  this.renderColumns.map((model, index) => {
                    return renderChildColumn(model, index);
                  }),
              ];
            },
          }}
        </el-table>
        {enablePagingBar && (
          <iBizGridPagination
            total={state.total}
            curPage={state.curPage}
            size={state.size}
            onChange={this.onPageChange}
            onPageSizeChange={this.onPageSizeChange}
            onPageRefresh={this.onPageRefresh}
          ></iBizGridPagination>
        )}
      </iBizControlBase>
    );
  },
});
